package com.lyn.common.base;

import com.alibaba.fastjson.JSONArray;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.TableMapping;
import com.lyn.common.kit.StringKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public abstract class BaseService {
    protected Logger logger = LoggerFactory.getLogger(BaseService.class);

    protected static final String updateOk = "保存成功";
    protected static final String updatePartOk = "部分记录保存失败";
    protected static final String updateFail = "保存失败";
    protected static final String updateEmpty = "未保存任何数据";

    protected static final String getOk = "获取成功";


    public abstract Model<?> getDao();

    /**
     * 获取table名称
     * 测试通过
     * @return tableName
     */
    public String getTableName() {
        if(getDao()==null){
            logger.error("请实现getDao()方法,且不能返回null");
        }
        return TableMapping.me().getTable(getDao().getClass()).getName();
    };

    /**
     * 插入一条记录
     * 测试通过
     * @param entity
     * @return
     */
    public Result baseInsert(Model<?> entity) {
        if(entity.save()) {
            return Result.ok(updateOk);
        } else {
            return Result.fail(updateFail);
        }
    }

    /**
     * 根据主键更新一条记录
     * 测试通过
     * @param entity
     * @return
     */
    public Result baseUpdateById(Model<?> entity) {
        if(entity.update()) {
            return Result.ok(updateOk);
        } else {
            return Result.fail(updateFail);
        }
    }

    /**
     * 根据主键更新多条记录
     * 测试通过
     * @param ja json数组
     * @param clazz
     * @return
     */
    public Result baseUpdatesById(JSONArray ja, Class<? extends Model<?>> clazz) {
        int result = 0;
        for(int i=0; i<ja.size(); i++) {
            Model model = ja.getObject(i, clazz);
            if(model.update()) {
                result++;
            }
        }
        if(result==ja.size()) {
            return Result.ok(updateOk);
        } else {
            return Result.fail(updateFail);
        }
    }

    /**
     * 根据主键获取单条记录
     * 测试通过
     * @param id
     * @return
     */
    public Result baseGetById(int id) {
        Model<?> entity = getDao().findById(id);
        return Result.ok(getOk, entity);
    }

    /**
     * 根据主键获取单条记录
     * 测试通过
     * @param id
     * @return
     */
    public Result baseGetById(String id) {
        Model<?> entity = getDao().findById(id);
        return Result.ok(getOk, entity);
    }


    /**
     * 拼接出单表update语句：update tbl set a=aa, b=bb where c=cc and d=dd and e=ee;
     * @param setKeys
     * @param whereKeys
     * @return
     */
    public String getUpdateSql(List<String> setKeys, List<String> whereKeys) {
        String sql = "update " + getTableName() + " set ";
        for(String key : setKeys) {
            sql += key+"?,";
        }
        sql = sql.substring(0, sql.length()-1);
        if(whereKeys!=null) {
            sql += " where ";
            for(String key :whereKeys) {
                sql += key+"? and ";
            }
            sql = sql.substring(0, sql.length()-5);
        }
        return sql;
    }


    /**
     * 拼接出单表全查询语句：select * from tbl
     * 测试通过
     * @return
     */
    public String getSelectSql() {
        return "select * from " + getTableName();
    }

    /**
     * 拼接出带条件的单表查询语句
     * 测试通过
     * @param param
     * @return
     */
    public String getSelectSql(List<String> param) {
        String sql = getSelectSql() + " where ";
        for(String p : param) {
            sql += param + "? and ";
        }
        sql = sql.substring(0, sql.length()-4);
        return sql;
    }


    /**
     * 执行自定义条件的单表update
     * 测试通过
     * @param setParam
     * @param whereParam
     * @return
     */
    public Result baseCustomUpdate(Kv setParam, Kv whereParam) {
        String sql = "update " + getTableName() + " set ";
        List<Object> paramList = new ArrayList<>();
        Set<String> keys = setParam.keySet();
        for(String key : keys) {
            paramList.add(setParam.get(key));
            key = StringKit.humpToUnderline(key);
            sql += key+"=?,";
        }
        sql = sql.substring(0, sql.length()-1);
        if(whereParam!=null) {
            sql += " where ";
            keys = whereParam.keySet();
            for(String key :keys) {
                Object value = whereParam.get(key);
                key = StringKit.humpToUnderline(key);
                if(value==null) {
                    sql += key + " and ";
                } else {
                    sql += key+"? and ";
                    paramList.add(value);
                }
            }
            sql = sql.substring(0, sql.length()-5);
        }
        int count = Db.update(sql, paramList.toArray());
        if(count>0) {
            return Result.ok(updateOk);
        } else if(count==0) {
            return Result.fail(updateEmpty);
        } else {
            return Result.fail(updateFail);
        }
    }

    /**
     * 执行自定义条件单表查询
     * 测试通过
     * @param fields 查询字段，例如：id, name, birthday，传入空则等价于select *
     * @param whereParam key=feild name, value=value
     * @return
     */
    public Result baseCustomSelect(String fields, Kv whereParam) {
        List<Object> paramList = new ArrayList<>();
        String sql = null;
        if (StrKit.isBlank(fields)) {
            sql = getSelectSql();
        }
        else {
            fields = StringKit.humpToUnderline(fields);
            sql = "select " + fields +" from " + getTableName();
        }
        sql += " where ";
        Set<String> keys = whereParam.keySet();
        for(String key : keys) {
            Object value = whereParam.get(key);
            if(value==null) {
                sql += key + " and ";
            } else {
                paramList.add(value);
                key = StringKit.humpToUnderline(key);
                sql += key + "? and ";
            }
        }
        sql = sql.substring(0, sql.length()-4);
        List<?> list = getDao().find(sql, paramList.toArray());
        return Result.ok(getOk, list);
    }

    /**
     * 自定义条件分页查询单表
     * @param pageNumber
     * @param pageSize
     * @param selectSql
     * @param whereParam key请带上符号，例如{id>,0}
     * @return
     */
    public Result baseCustomGetByPage(int pageNumber, int pageSize, String selectSql, Kv whereParam) {
        List<Object> paramList = new ArrayList();
        String whereSql = " from " + getTableName() + " where 1=1 and ";
        List<Object> list = new ArrayList<Object>();
        Set<String> keys = whereParam.keySet();
        for(String key : keys) {
            Object value = whereParam.get(key);
            if(value==null) { //如果值为空，则由key来拼接sql，比如key=field is null
                whereSql += key + " and ";
            } else {
                whereSql += key+"? and ";
                paramList.add(value);
            }
        }
        whereSql = whereSql.substring(0, whereSql.length()-4);
        Page<?> pages = getDao().paginate(pageNumber, pageSize, selectSql, whereSql, paramList.toArray());
        return Result.ok(getOk, pages);
    }



}





















































